package com.rsc.learningbar.service;

import com.rsc.learningbar.dao.StudentPlanRepository;
import com.rsc.learningbar.entity.StudentPlan;
import com.rsc.learningbar.vo.Plan;
import com.rsc.learningbar.vo.StudentPlanVo;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import javax.websocket.RemoteEndpoint;
import javax.websocket.Session;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.TimeUnit;

@Component
public class WebSocketPlanService implements ApplicationContextAware {

    private static ApplicationContext applicationContext;
    private static DelayQueue delayQueue;
    private static StudentPlanRepository studentPlanRepository;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        WebSocketPlanService.applicationContext = applicationContext;
        WebSocketPlanService.delayQueue = applicationContext.getBean(DelayQueue.class);
        WebSocketPlanService.studentPlanRepository = applicationContext.getBean(StudentPlanRepository.class);

    }

    public static final Map<Long, Session> ONLINE_USER_SESSIONS = new ConcurrentHashMap<>();

    // 单用户推送
    public static void sendMessage(Session session, String message) {
        if (session == null) {
            return;
        }
        final RemoteEndpoint.Basic basic = session.getBasicRemote();
        if (basic == null) {
            return;
        }
        try {
            basic.sendText(message);
        } catch (IOException e) {
            System.out.println("sendMessage IOException " + e);
        }
    }

    // 全用户推送
    public static void sendMessageAll(String message) {
        ONLINE_USER_SESSIONS.forEach((sessionId, session) -> sendMessage(session, message));
    }

    public static void setPlanQueue(Long userId) {
        // 发送过期的学习提醒
        List<StudentPlan> plans = studentPlanRepository.findTodoPlanByUserId(Long.valueOf(userId));
        for (StudentPlan plan : plans) {
            // 放入延迟队列
            StudentPlanVo info = new StudentPlanVo();
            info.setId(plan.getId());
            info.setUserId(Long.valueOf(userId));
            info.setStudentMissionId(plan.getStudentMissionId());
            info.setStudentMissionName(plan.getStudentMissionName());

            LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime dateTime = LocalDateTime.parse(plan.getRemindTime(), formatter);

            Duration duration = Duration.between(localDateTime, dateTime);

            long seconds = duration.getSeconds();
            Plan p = new Plan(info, seconds, TimeUnit.SECONDS);
            if (!delayQueue.contains(p)) {
                delayQueue.put(p);
            }
        }
    }

}